#ifndef __BS_PROTOCOL_H__
#define __BS_PROTOCOL_H__
#include <stdint.h>
#include "gd32f4xx.h"
#include "bs_app.h"


#define DBG_ERROR_GPIO_PIN                   GPIO_PIN_1
#define DBG_ERROR_GPIO_PORT                  GPIOB
#define DBG_ERROR_GPIO_CLK                   RCU_GPIOB

#define DBG_RUN_GPIO_PIN                   GPIO_PIN_2
#define DBG_RUN_GPIO_PORT                  GPIOA
#define DBG_RUN_GPIO_CLK                   RCU_GPIOA

#define DBG_SEND_GPIO_PIN                   GPIO_PIN_3
#define DBG_SEND_GPIO_PORT                  GPIOA
#define DBG_SEND_GPIO_CLK                   RCU_GPIOA

//DATA DIR 
#define DATA_DIR_GPIO_PIN                   GPIO_PIN_2
#define DATA_DIR_GPIO_PORT                  GPIOB
#define DATA_DIR_GPIO_CLK                   RCU_GPIOB

//DATA IN
#define DATA_IN_GPIO_PIN                    GPIO_PIN_5
#define DATA_IN_GPIO_PORT                   GPIOB
#define DATA_IN_GPIO_CLK                    RCU_GPIOB

//DATA OUT
#define DATA_OUT_GPIO_PIN                   GPIO_PIN_4
#define DATA_OUT_GPIO_PORT                  GPIOB
#define DATA_OUT_GPIO_CLK                   RCU_GPIOAB

//CLK OUT
#define CLK_GPIO_PIN                    	GPIO_PIN_3
#define CLK_GPIO_PORT                   	GPIOB
#define CLK_GPIO_CLK                    	RCU_GPIOB



#define DBG_TMP_GPIO_PIN                   GPIO_PIN_1
#define DBG_TMP_GPIO_PORT                  GPIOB
#define DBG_TMP_GPIO_CLK                   RCU_GPIOB



#define DBG_ERROR_SET				      GPIO_BOP(DBG_ERROR_GPIO_PORT) = DBG_ERROR_GPIO_PIN;
#define DBG_ERROR_CLR					  GPIO_BC(DBG_ERROR_GPIO_PORT) = DBG_ERROR_GPIO_PIN;

#define DBG_TMP_SET						  GPIO_BOP(DBG_TMP_GPIO_PORT) = DBG_TMP_GPIO_PIN;
#define DBG_TMP_CLR						  GPIO_BC(DBG_TMP_GPIO_PORT) = DBG_TMP_GPIO_PIN;

#define DBG_RUN_SET						  GPIO_BOP(DBG_RUN_GPIO_PORT) = DBG_RUN_GPIO_PIN;
#define DBG_RUN_CLR						  GPIO_BC(DBG_RUN_GPIO_PORT) = DBG_RUN_GPIO_PIN;

#define DBG_SEND_SET				      GPIO_BOP(DBG_SEND_GPIO_PORT) = DBG_SEND_GPIO_PIN;
#define DBG_SEND_CLR			          GPIO_BC(DBG_SEND_GPIO_PORT) = DBG_SEND_GPIO_PIN;

#define CLK_DIR_OUT						  GPIO_BOP(CLK_DIR_GPIO_PORT) = CLK_DIR_GPIO_PIN;
#define CLK_DIR_IN						  GPIO_BC(CLK_DIR_GPIO_PORT) = CLK_DIR_GPIO_PIN;

#define CLK_SET							  GPIO_BOP(CLK_GPIO_PORT) = CLK_GPIO_PIN;
#define CLK_CLR						      GPIO_BC(CLK_GPIO_PORT) = CLK_GPIO_PIN;

#define DATA_SET					      GPIO_BOP(DATA_OUT_GPIO_PORT) = DATA_OUT_GPIO_PIN;
#define DATA_CLR					      GPIO_BC(DATA_OUT_GPIO_PORT) = DATA_OUT_GPIO_PIN;

#define DBG_USB_SET					      GPIO_BOP(DBG_USB_GPIO_PORT) = DBG_USB_GPIO_PIN;
#define DBG_USB_CLR						  GPIO_BC(DBG_USB_GPIO_PORT) = DBG_USB_GPIO_PIN;

#define DATA_DIR_OUT					  GPIO_BOP(DATA_DIR_GPIO_PORT) = DATA_DIR_GPIO_PIN;
#define DATA_DIR_IN						  GPIO_BC(DATA_DIR_GPIO_PORT) = DATA_DIR_GPIO_PIN;

#define DATA_READ					      (GPIO_ISTAT(DATA_IN_GPIO_PORT) & DATA_IN_GPIO_PIN)	//if RESET


#define BS_PROTOCOL_DELAY()	{\
	__nop(); \
}

#define BS_PROTOCOL_DATA_DIR_IN()	{\
	DATA_DIR_IN\
}

#define BS_PROTOCOL_DATA_DIR_OUT()	{\
	DATA_DIR_OUT;\
}


#define DBG_RUN_TOGGLE                    GPIO_TG(GPIOB) = GPIO_PIN_0;
#define DBG_WRITE_TOGGLE                  GPIO_TG(GPIOB) = GPIO_PIN_0;
#define DBG_BSY_TOGGLE                    GPIO_TG(GPIOB) = GPIO_PIN_7;
#define DBG_BSY2_TOGGLE                   GPIO_TG(GPIOB) = GPIO_PIN_8;

#define DBG_IDLE_SET                     if(ctx->channel == 0) GPIO_BOP(GPIOB) = GPIO_PIN_6;\
                                          else GPIO_BOP(GPIOB) = GPIO_PIN_0;
#define DBG_IDLE_CLR                     if(ctx->channel == 0) GPIO_BC(GPIOB) = GPIO_PIN_6;\
                                          else GPIO_BC(GPIOB) = GPIO_PIN_0;


void bs_protocol_config(bs_writer_ctx_t *ctx, unsigned char channel);

int __v1_protocol_ioctl(bs_writer_ctx_t *ctx, bs_writer_trans_t cmd);
int __v1_protocol_write_sync(bs_writer_ctx_t *ctx, unsigned char *buf, int size);
void __v1_protocol_write_async(bs_writer_ctx_t *ctx, unsigned char *buf, int size);
int __v1_protocol_read(bs_writer_ctx_t *ctx, unsigned char * rdb, int size);

int __v2_protocol_ioctl(bs_writer_ctx_t *ctx, bs_writer_trans_t cmd);
int __v2_protocol_write_sync(bs_writer_ctx_t *ctx, unsigned char *buf, int size);
void __v2_protocol_write_async(bs_writer_ctx_t *ctx, unsigned char *buf, int size);
int __v2_protocol_read(bs_writer_ctx_t *ctx, unsigned char * rdb, int size);
void __v2_protocol_read_async(bs_writer_ctx_t *ctx, unsigned char *buf, int size);

int bs_fw_fill_data(bs_writer_ctx_t *ctx, int size);

#define bs_protocol_write_sync(ctx, b, s)     if (__v2_protocol_write_sync(ctx, b, s)) {\
                                                  ctx->schedu = WRITER_WR_TIME_OUT;\
                                                  return 1;\
                                              }

#define bs_protocol_read(ctx, b, s)           if (__v2_protocol_read(ctx, b, s)) {\
                                                  ctx->schedu = WRITER_RD_TIME_OUT;\
                                                  return 1;\
                                              }

#define bs_protocol_ioctl(ctx, c)             __v2_protocol_ioctl(ctx, c)
#define bs_protocol_write_async(ctx, b, s, n)    __v2_protocol_write_async(ctx, b, s);
                                            //   if(n == 0) GPIO_BOP(GPIOB) = GPIO_PIN_7;\
                                            //   else GPIO_BC(GPIOB) = GPIO_PIN_7;
#define bs_protocol_read_async(ctx, b, s)     __v2_protocol_read_async(ctx, b, s)

#endif
